package com.cdgeekcamp.redas.wechat.service;

import com.cdgeekcamp.redas.wechat.aes.AesException;
import com.cdgeekcamp.redas.wechat.component.EncryptAndDecryptMessage;
import com.cdgeekcamp.redas.wechat.config.WeChatConfig;
import com.cdgeekcamp.redas.wechat.entity.MessageBaseEntity;
import com.cdgeekcamp.redas.wechat.factory.MessageFactory;
import com.google.gson.Gson;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;

@Service
public class WeChatService {

    @Autowired
    private WeChatConfig weChatConfig;

    @Autowired
    private EncryptAndDecryptMessage encryptAndDecryptMessage;

    @Autowired
    private MessageFactory messageFactory;

    /**
     * 在配置微信公众号的基础配置时，微信会访问的的方法
     * @param request
     * @param response
     * @throws IOException
     */
    public void verifyComeFromWeChat(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String signature = request.getParameter("signature");
        String echostr = request.getParameter("echostr");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");

        String token = weChatConfig.getToken();
        String[] arrayString = {token, timestamp, nonce };
        Arrays.sort(arrayString); // 排序
        String joinString = arrayString[0] + arrayString[1] + arrayString[2];

        // SHA1加密
        String digest = DigestUtils.sha1Hex(joinString);

        if (digest.equals(signature)) {
            response.getWriter().print(echostr);
        }else {
            response.getWriter().print("Identity verify failed, request does not come from WeChat");
        }
    }

    /**
     * 处理微信用户，触发的一系列动作消息
     * @param request
     * @param response
     * @param requestBody
     * @throws AesException
     */
    public void dealWithMessage(HttpServletRequest request, HttpServletResponse response, String requestBody) throws Exception {
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String msgSignature = request.getParameter("msg_signature");

        // 解密
        String decryptMsg = encryptAndDecryptMessage.decryptMessage(msgSignature, timestamp, nonce, requestBody);
        Map<String, String> msgMap = new XmlProcess().toMap(decryptMsg);
        Type msgType = messageFactory.getBean(msgMap);

        // 根据用户请求，返回相应的消息
        Gson gson = new Gson();
        String jsonString = gson.toJson(msgMap);
        MessageBaseEntity receiveMsg = (MessageBaseEntity) gson.fromJson(jsonString, msgType);
        String replyMsg = receiveMsg.doReply();

        // 加密回复消息
        String encryptMsg = encryptAndDecryptMessage.encryptMessage(replyMsg, timestamp, nonce);
        // 返回xml消息给微信
        response.getWriter().print(encryptMsg);
    }
}
